package wiki.tiecode;

import com.tiecode.compiler.toolchain.env.Context;
import com.tiecode.compiler.toolchain.env.Options;
import com.tiecode.compiler.toolchain.env.Platform;
import com.tiecode.compiler.code.CodeServiceKit;
import java.io.File;
import java.util.LinkedList;
import com.tiecode.compiler.api.file.TiecodeFileObject;
import com.tiecode.compiler.api.file.TiecodeSourceFile;
import java.util.concurrent.Executor;
import java.io.FileWriter;
import java.util.Collection;
import java.util.jar.Attributes.Name;
import com.tiecode.compiler.source.util.TreePath;
import java.io.StringWriter;
import com.tiecode.compiler.toolchain.tree.symbol.Symbol;
import java.util.ArrayList;
import java.util.List;

public class Autocomplete {
    private CodeServiceKit codeKit;
    private List<TiecodeFileObject> files;

    public void Initialization(Context context, String projectPath, String namespace) {
        try {
            Options opt = Options.instance(context);
            opt.namespace = namespace;
            opt.platform = Platform.ANDROID;
            this.codeKit = new CodeServiceKit(context, opt);
            this.files = new LinkedList<>();

            // 递归获取文件
            File rootDir = new File(projectPath);
            if (rootDir.exists() && rootDir.isDirectory()) {
                addFilesRecursively(rootDir, "");
            }

            codeKit.preCompile(files);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void addFilesRecursively(File dir, String relativePath) {
        if (dir.exists() && dir.isDirectory()) {
            if (dir.getName().equals(".git") || dir.getName().equals("绳包")) {
                return;
            }

            // 遍历当前目录下的所有文件和子目录
            for (File file : dir.listFiles()) {
                String currentRelativePath = relativePath + file.getName();

                if (file.isDirectory()) {
                    // 递归处理子目录
                    addFilesRecursively(file, currentRelativePath + File.separator);
                } else if (file.isFile() && file.getName().endsWith(".t")) {
                    // 只处理 .t 后缀的文件
                    TiecodeSourceFile tmp = new TiecodeSourceFile(file);
                    System.out.println(tmp.toPathString());
                    files.add(tmp);
                }
            }
        }
    }

    public void IncrementalUpdate(String Objectfile) {
        try {
            for (int i = 0; i < files.size(); i++) {
                String fileName = files.get(i).toString().split(",")[0].split("=")[1].replace("'", "");
                if (fileName.equals(Objectfile)) {
                    codeKit.update(files.get(i));
                    FileWriter writer = new FileWriter(files.get(i).toPathString());
                    writer.write(files.get(i).getContent().toString());
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public List<String> TakeAnnotation(String Objectfile, int line, int column) {
        List<String> comp = new ArrayList<>();
        try {
            int start = Math.max(0, column - 1);
            for (int i = 0; i < files.size(); i++) {
                if (files.get(i).getName().equals(Objectfile)) {
                    // Assuming findCompletionAt is correctly implemented and returns a valid TreePath.
                    TreePath treePath = codeKit.findCompletionAt(files.get(i), line, column);
                    while (start > 0 && !Character.isWhitespace(files.get(i).getContent().charAt(start - 1))) {
                        start--;
                    }
                    String cpf = files.get(i).getContent().toString().substring(start, column).trim();
                    // Adjusting the type of the collection to match the return type of getAnnotationNames.
                    Collection<com.tiecode.compiler.api.descriptor.Name> names = codeKit.getAnnotationNames();
                    for (com.tiecode.compiler.api.descriptor.Name name : names) {
                        if (name.toString().startsWith(cpf)) {
                            comp.add(name.toString());
                        }
                    }
                }
            }
            return comp;
        } catch (Exception ee) {
            ee.printStackTrace();
        }
        return comp;
    }

    public List<String> FetchIdentifier(String Objectfile, int line, int column) {
        List<String> comp = new ArrayList<>();
        try {

            int start = Math.max(0, column - 1);
            for (int i = 0; i < files.size(); i++) {
                if (files.get(i).getName().equals(Objectfile)) {
                    TreePath treePath = codeKit.findCompletionAt(files.get(i), line, column);
                    while (start > 0 && !Character.isWhitespace(files.get(i).getContent().charAt(start - 1))) {
                        start--;
                    }
                    String cpf = files.get(i).getContent().toString().substring(start, column).trim();
                    Collection<Symbol.ClassSymbol> classes = codeKit.getAllClasses();
                    for (Symbol.ClassSymbol classSym : classes) {
                        if (classSym.name.toString().startsWith(cpf)) {
                            comp.add(classSym.name.toString());
                        }
                    }
                }
            }
            return comp;
        } catch (Exception ee) {
            ee.printStackTrace();
        }
        return comp;
    }
}